<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>

</html>
<script>
    //一.普通事件,如果出现相同的事件,后面会覆盖前面的。
    // DOM 0级事件：事件类型相同的情况下,一个元素对象上面只能绑定一个事件处理函数,否则会出现覆盖。
    // 取消DOM 0级事件：将结果赋值为null.
    // document.onclick = function() {
    //     alert('张三写的代码');
    // };
    // document.onclick = function() {
    //     alert('李四写的代码');
    // };

    // document.onclick = null; //取消普通事件


    //二.事件绑定,事件监听,事件侦听
    //DOM 2级事件：事件类型相同的情况下,一个元素对象上面可以绑定多个事件处理函数,顺序执行。
    //1.标准：元素对象.addEventListener(事件类型,事件处理函数,是否捕获);
    //事件类型：没有on，直接使用click,mouseover,mouseout,mousedown,keydown,keyup...
    //事件处理函数：函数给事件。
    //是否捕获：参数可以省略,默认是false(冒泡), true(捕获)
    // document.addEventListener('click', function() {
    //     alert('张三的代码');
    // }, false);

    // document.addEventListener('click', function() {
    //     alert('李四的代码');
    // }, false);

    //非标准：元素对象.attachEvent(事件类型,事件处理函数)
    //事件类型：有on，直接使用onclick,onmouseover...
    //事件处理函数：函数给事件。
    // document.attachEvent('onclick', function() {
    //     alert('张三的代码');
    // });
    // document.attachEvent('onclick', function() {
    //     alert('李四的代码');
    // });

    //经典的面试：IE的事件绑定和标准浏览器的事件绑定的区别。
    //1.事件类型不一样。
    //2.参数个数不一样。
    //3.执行顺序不一样。标准正序，非标准倒序。
    //4.this指向不一样。标准浏览器事件处理函数的this指向当前操作的元素对象。非标准this指向window。
    // document.addEventListener('click', function() {
    //     alert(this);//Document
    // }, false);

    // document.attachEvent('onclick', function() {
    //     alert(this); //window
    // });

    //事件绑定兼容写法。
    function addEvent(obj, etype, fn, bool) { //obj:元素对象 etype:事件类型  fn:事件处理函数  bool:是否捕获
        bool = bool || false; //早期设置默认值的方式。
        if (obj.addEventListener) { //标准浏览器
            obj.addEventListener(etype, fn, bool);
        } else { //IE浏览器
            obj.attachEvent('on' + etype, fn);
        }
    }

    function fnTest() {
        alert('事件绑定的测试');
    }

    addEvent(document, 'click', fnTest);


    //三.取消事件绑定。
    //注意：移除事件监听的参数和添加事件监听的参数是一致的。
    //标准：元素对象.removeEventListener(事件类型,事件处理函数,是否捕获);
    //非标准：元素对象.detachEvent(事件类型,事件处理函数);

    function removeEvent(obj, etype, fn, bool) { //obj:元素对象 etype:事件类型  fn:事件处理函数  bool:是否捕获
        bool = bool || false; //早期设置默认值的方式。
        if (obj.removeEventListener) { //标准浏览器
            obj.removeEventListener(etype, fn, bool);
        } else { //IE浏览器
            obj.detachEvent('on' + etype, fn);
        }
    }

    removeEvent(document, 'click', fnTest); //删除
    // console.log(function() {} == function() {}); //false


    //四.注意情况
    //1.取消默认行为，return false不能取消事件绑定里面的默认行为，只能使用preventDefault或者returnvalue
    //2.DOM 2级事件取代DOM 0级事件,反之不行。
</script>